﻿import flash.geom.Point;
import kliment.controls.ControlsAbstract;
import kliment.events.Event;
import kliment.events.MouseGestureEvent;
import kliment.geom.draw.LineStyle;
import kliment.geom.SimplePoint;
import kliment.display.MCC;
import mx.events.EventDispatcher;

/**
 * ...
 * @author	Kliment
 * @version	2.4.6
 */
class kliment.controls.MouseGesture extends ControlsAbstract {	
	private var _target_mc:MovieClip;
	private var _intervalID:Number;
	public var delay:Number;
	public var minSize:Number;
	private var _startPoint:SimplePoint;
	private var _endPoint:SimplePoint;
	private var _points:Array;
	private var _isPress:Boolean = false;
	
	public var enableDraw:Boolean = true;
	public var lineStyle:LineStyle;
	private var _draw_mc:MovieClip; 
	
	public function MouseGesture(space_mc:MovieClip, delay:Number, minSize:Number) {
		_target_mc = space_mc;
		this.delay = delay;
		this.minSize = minSize;
		lineStyle = new LineStyle(1, 0x000000);
		_init();
	}
	
	private function _init():Void {
		_isPress = false;
		Mouse.addListener(this);
		EventDispatcher.initialize(this);
	}
	
	private function onMouseDown():Void {
		if (!_enable) 
			return;
		
		_points = new Array();
		_endPoint = null;
		_startPoint = new SimplePoint(_target_mc._xmouse, _target_mc._ymouse);
		
		if (MCC.hitTestBoundsMouse(_target_mc)) {
			_isPress = true;
			if (enableDraw) {
				_draw_mc = MCC.create();
				_draw_mc.lineStyle(lineStyle.thickness, lineStyle.color, lineStyle.alpha, lineStyle.pixelHinting, lineStyle.noScale, lineStyle.capsStyle, lineStyle.jointStyle, lineStyle.miterLimit);
				_draw_mc.moveTo(_draw_mc._xmouse, _draw_mc._ymouse);
			}
			_intervalID = setInterval(this, '_checkInterval', delay);
		} else if (!_target_mc._target){
			remove();
		}
	}
	
	private function onMouseUp():Void {
		_endPoint = new SimplePoint(_target_mc._xmouse, _target_mc._ymouse);
		if (_isPress) 
			_checkInterval();
		_isPress = false;
	}
	
	private function onMouseMove():Void {
		if (_isPress) {
			var pos:Point = new Point(_target_mc._xmouse, _target_mc._ymouse);
			_points.push(pos);
			if (_target_mc && enableDraw) {
				_draw_mc.lineTo(_draw_mc._xmouse, _draw_mc._ymouse);
			}
			_onMove(pos);
		}
	}
	
	private function _checkInterval():Void {
		MCC.remove(_draw_mc);
		clearInterval(_intervalID);
		_isPress = false;
		if (_endPoint) 
			_checkGesture();
		_points = null;
	}
	
	public function set enable(value:Boolean):Void {
		if (super.enable == value) return;
		if (!value) {
			clearInterval(_intervalID);
			_endPoint = null;
			_startPoint = null;
		}
		super.enable = value;
	}
	
	private var _distance:Number = 0;
	private function _checkGesture():Void {
		var width:Number = Math.abs(_startPoint.x - _endPoint.x);
		var height:Number = Math.abs(_startPoint.y - _endPoint.y);
		
		if (width > height) { 						// horizontal
			_distance = width;
			if (width >= minSize) {
				if (_startPoint.x > _endPoint.x) 	// to left
					_onSlideLeft(width);
				else 								// to right
					_onSlideRight(width);
			}
		} else if (width < height) { 				// vertical
			_distance = height;
			if (height >= minSize) {
				if (_startPoint.y > _endPoint.y) 	// to up
					_onSlideUp(height);
				else 								// to down
					_onSlideDown(height);
			}
		}
	}
	
	private function _onSlideRight(distance:Number):Void {
		dispatchEvent(new MouseGestureEvent(MouseGestureEvent.SLIDE_RIGHT, this, distance));
	}
	private function _onSlideLeft(distance:Number):Void {
		dispatchEvent(new MouseGestureEvent(MouseGestureEvent.SLIDE_LEFT, this, distance));
	}
	private function _onSlideDown(distance:Number):Void {
		dispatchEvent(new MouseGestureEvent(MouseGestureEvent.SLIDE_DOWN, this, distance));
	}
	private function _onSlideUp(distance:Number):Void {
		dispatchEvent(new MouseGestureEvent(MouseGestureEvent.SLIDE_UP, this, distance));
	}
	
	private function _onMove(pos:Point):Void {
		dispatchEvent(new MouseGestureEvent(MouseGestureEvent.MOVE, this, _distance));
	}
	
	public function remove():Void {
		clearInterval(_intervalID);
		Mouse.removeListener(this);
		delete this;
	}
	
	public function addEventListener(eventType:String, handler:Function):Void {  }
	
	public function dispatchEvent(event:Event):Void {  }
	
	public function removeEventListener(eventType:String, handler:Function):Void {  }
}